#ifndef Z_INC_BLE_TYPE_H
#define Z_INC_BLE_TYPE_H

#include <zephyr/types.h>

#ifdef __cplusplus
extern "C" {
#endif

#define BLE_CMD_BASE 0x10
#define BLE_EVT_BASE 0x40

typedef enum
{
    BLE_CMD_SCAN_START = BLE_CMD_BASE,
    BLE_CMD_SCAN_STOP,
    BLE_CMD_CONNECT,
    BLE_CMD_DISCONNECT,
    BLE_CMD_PRIMARY_DISCOVER,
    BLE_CMD_SECONDARY_DISCOVER,
    BLE_CMD_CHARACTERISTIC_DISCOVER,
    BLE_CMD_DESCRIPTOR_DISCOVER,
    BLE_CMD_ATTRIBUTE_DISCOVER,
    BLE_CMD_READ,
    BLE_CMD_WRITE,
    BLE_CMD_ADV_START,
    BLE_CMD_ADV_STOP,
    BLE_CMD_CONNECTED_LIST,
} bt_le_cmd_list_t;

typedef enum
{
    BLE_EVT_SCAN_RESULT = BLE_EVT_BASE,
    BLE_EVT_CONNECTED,
    BLE_EVT_DISCONNECTED,
    BLE_EVT_PRIM_SRVC_DISC,
    BLE_EVT_SECOND_DISC,
    BLE_EVT_CHAR_DISC,
    BLE_EVT_DESC_DISC,
    BLE_EVT_ATT_DISC,
    BLE_EVT_READ,
    BLE_EVT_WRITE,
    BLE_EVT_HVX,
    BLE_EVT_CONNECTED_LIST,
    BLE_EVT_TIMEOUT_SCAN,
} bt_le_evt_list_t;

typedef struct
{
    uint8_t *p_data;
    uint16_t len;
} bt_le_adv_data_t;

typedef struct
{
    uint8_t type;
    uint8_t addr[6];
} bt_le_addr_le_t;

typedef struct
{
    uint8_t count;
    bt_le_addr_le_t addr[10];
} bt_le_connected_list_t;

typedef struct
{
    uint16_t tx_max_len;
    uint16_t tx_max_time;
    uint16_t rx_max_len;
    uint16_t rx_max_time;
} bt_le_conn_data_len_info_t;

typedef struct
{
    uint8_t tx_phy;
    uint8_t rx_phy;
} bt_le_conn_phy_info_t;

typedef struct
{
    uint16_t interval;
    uint16_t latency;
    uint16_t timeout;
} bt_le_conn_param_updated_t;

typedef struct
{
    uint16_t interval_min;
    uint16_t interval_max;
    uint16_t latency;
    uint16_t timeout;
} bt_le_conn_param_t;

typedef struct
{
    uint16_t tx;
    uint16_t rx;
} bt_le_evt_att_mtu_updated_t;

typedef struct
{
    bt_le_conn_data_len_info_t param;
} bt_le_evt_data_len_updated_t;

typedef struct
{
    bt_le_conn_phy_info_t param;
} bt_le_evt_phy_updated_t;

typedef struct
{
    bt_le_conn_param_updated_t param;
} bt_le_evt_param_updated_t;

typedef struct
{
    bt_le_conn_param_t param;
} bt_le_evt_param_req_t;

typedef struct
{
    uint8_t reason;
} bt_le_evt_disconnected_t;

typedef struct
{
    uint8_t err;
} bt_le_evt_connected_t;

typedef struct
{
    uint16_t conn_handle;
    uint8_t type;
    uint8_t role;
    uint8_t id;
    uint8_t err;
    uint8_t conn_state;
} bt_le_conn_evt_hdr_t;

typedef struct
{
    uint8_t src;
} bt_le_evt_scan_timeout_t;

typedef struct
{
    bt_le_addr_le_t peer_addr;
    uint8_t adv_type;
    uint8_t sid;
    int8_t rssi;
    int8_t tx_power;
    uint16_t adv_props;
    uint16_t interval;
    uint8_t primary_phy;
    uint8_t secondary_phy;
    bt_le_adv_data_t adv_data;
} bt_le_evt_scan_result_t;

typedef struct
{
    uint16_t conn_handle;
    union {
        bt_le_evt_att_mtu_updated_t mtu_updated;
    } params;
} bt_le_gatt_evt_t;

typedef struct
{
    bt_le_conn_evt_hdr_t header;
    union {
        bt_le_evt_connected_t connected;
        bt_le_evt_disconnected_t disconnected;
        bt_le_evt_param_req_t param_req;
        bt_le_evt_param_updated_t param_updated;
        bt_le_evt_phy_updated_t phy_updated;
        bt_le_evt_data_len_updated_t ata_len_updated;
    } params;
} bt_le_conn_evt_t;

typedef struct
{
    union {
        bt_le_evt_scan_result_t result;
        bt_le_evt_scan_timeout_t timeout;
    } params;
} bt_le_scan_evt_t;

typedef struct
{
    union {
        bt_le_connected_list_t connected_list;
    } params;
} bt_le_common_evt_t;

typedef struct
{
    uint16_t evt_id;
    uint16_t evt_len;
} bt_le_evt_hdr_t;

#pragma pack(1)
typedef struct
{
    bt_le_evt_hdr_t header;
    union {
        bt_le_common_evt_t common_evt;
        bt_le_scan_evt_t scan_evt;
        bt_le_conn_evt_t conn_evt;
        bt_le_gatt_evt_t gatt_evt;
    } evt;
} bt_le_evt_t;

#ifdef __cplusplus
}
#endif

#endif // Z_INC_BLE_TYPE_H